﻿namespace Oddo.Concept.Crm.Common.Models
{
    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Runtime.Serialization;
    using Oddo.Concept.Crm.Common.Extensions;
    using Oddo.Concept.Crm.Common.Interfaces;
    using Newtonsoft.Json;

    /// <summary>
    /// Classe de base d'un modele métier
    /// </summary>
    public abstract class ModelBase : INotifyPropertyChangedEx
    {
        private bool _shouldNotifyPropertyChanged = true;

        /// <summary>
        ///  Evenement declenché lors du changement d'une propriété
        /// </summary>
        [field : NonSerialized]
        [field : JsonIgnore]
        public virtual event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// Obtient ou définit si l'evenment PropertyChanged doit être declenché
        /// </summary>
        [JsonIgnore]
        public bool ShouldNotifyPropertyChanged
        {
            get { return _shouldNotifyPropertyChanged; }
            set { _shouldNotifyPropertyChanged = value; }
        }

        /// <summary>
        /// Méthode appellée lorsque la deserialization de l'instance est terminée
        /// </summary>
        [OnDeserialized]
        protected internal void OnDeserialized(StreamingContext context)
        {
            // reactive la notification de changement d'une propriété
            _shouldNotifyPropertyChanged = true;
            AfterDeserialization();
        }
        /// <summary>
        /// Méthode appellée après la deserialization de l'instance
        /// </summary>
        public virtual void AfterDeserialization(){}

        /// <summary>
        /// Notifie le changement d'une propriété
        /// </summary>
        /// <param name="propertyname">Le nom de la propriété modifiée</param>
        /// <remarks>La valeur de la propriété ShouldNotifyPropertyChanged est ignoré</remarks>
        public void NotifyPropertyChanged(string propertyname)
        {
            var handler = PropertyChanged;
            if(handler !=null)
                handler(this,new PropertyChangedEventArgs(propertyname));
        }
        /// <summary>
        /// Notifie le changement d'une propriété si la valeur de la propriété ShouldNotifyPropertyChanged vaut True
        /// </summary>
        protected internal void NotifyPropertyChanged<T>(Expression<Func<T>> propertyExpression)
        {
            this.RaisePropertyChanged(propertyExpression);
        }

    }
}